/*!
//      
//      \file	k2k_NanoX.c
//      
//      \author	Copyright 2010 Valentina Vuksic <vuksv1@bfh.ch>, Beat Liechti <liecb2@bfh.ch>
//      
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//      
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//      
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.
//
//      Abstract Data Type for Nano-X integration
//      
//      \brief		CAS-EBX-03 Projektarbeit 
//      			Valentina Vuksic (VUKSV1), Beat Liechti (LIECB2)
//      			Nano-X ADT for the k2k (Kaffee2000) application
//      \version	1.0
//      \date		2010-04-19
//      \remark		Last Modifications:
//      \remark  	v1.0, VUKSV1/LIECB2, 2010-04-19 Initial release
//
*/

#include <stdlib.h>
#include <string.h>

#include "k2k_GlobalDefines.h"
#include "k2k_NanoX.h"

#define STATE_TEXT_X	30
#define STATE_TEXT_Y	40
#define RSTR_TEXT_X		30
#define RSTR_TEXT_Y		100
#define RSTR_TEXT		"Ristretto S1"
#define RSTR_ICON_X		30
#define RSTR_ICON_Y		130
#define RSTR_ICON_W		50
#define RSTR_ICON_H		50
#define ESPR_TEXT_X		130
#define ESPR_TEXT_Y		100
#define ESPR_TEXT		"Espresso S2"
#define ESPR_ICON_X		130
#define ESPR_ICON_Y		130
#define ESPR_ICON_W		50
#define ESPR_ICON_H		50
#define MLKC_TEXT_X		230
#define MLKC_TEXT_Y		100
#define MLKC_TEXT		"Milkcoffee S3"
#define MLKC_ICON_X		230
#define MLKC_ICON_Y		130
#define MLKC_ICON_W		50
#define MLKC_ICON_H		50
#define CUP1_X			265
#define CUP1_Y			41
#define CUP2_X			285
#define CUP2_Y			41
#define CUP_W			10
#define CUP_H			10
#define CUPLINE1_X1		263
#define CUPLINE1_Y1		47
#define CUPLINE1_X2		277
#define CUPLINE1_Y2		47
#define CUPLINE2_X1		283
#define CUPLINE2_Y1		47
#define CUPLINE2_X2		297
#define CUPLINE2_Y2		47
#define ONOFF_X			290
#define ONOFF_Y			9
#define ONOFF_W			6
#define ONOFF_H			6

/* -- static function declarations -----------------------------------*/

static void k2k_NanoX_UpdateAnimation(k2k_NanoX *nanoX, GR_GC_ID gAnimID, int X, int Y, int H, int W, int *fillDegree);

/* -- ADT functions --------------------------------------------------*/

/*!
//
// Creates nanoX ADT "object"
// 
// \return pointer to the nanoX ADT
//
*/
k2k_NanoX* k2k_NanoX_Create()
{	
	k2k_NanoX *nanoX = NULL;
	nanoX = malloc(sizeof(k2k_NanoX));
	if (nanoX != NULL)
	{		
		/*! try to open the graphic device */
		if (GrOpen() < 0)	 
		{
			nanoX->err = k2k_NANOX_ERR_GROPEN_FAILED;
		}
		else
		{			
			/*! get information about screen */
			GrGetScreenInfo(&nanoX->screenInfo);
			/*! artificially limit to QVGA (320x240) */
			if (nanoX->screenInfo.cols > 320) 
			{
				nanoX->screenInfo.cols = 320;
			}
			if (nanoX->screenInfo.rows > 240) 
			{
				nanoX->screenInfo.rows = 240;
			}
			/*! calculate window size */
			nanoX->winSizeX = nanoX->screenInfo.cols - 2 * WIN_BORDER;
			nanoX->winSizeY = nanoX->screenInfo.rows - 2 * WIN_BORDER;
			/*! create root window */
			nanoX->gRootWinID = GrNewWindow(GR_ROOT_WINDOW_ID, WIN_BORDER, WIN_BORDER, nanoX->winSizeX, nanoX->winSizeY, WIN_BORDER, BLACK, YELLOW);
			/*! register desired events */
			GrSelectEvents(nanoX->gRootWinID, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_CLOSE_REQ | GR_EVENT_MASK_TIMER);
			/*! show the window */
			GrMapWindow(nanoX->gRootWinID);
			/*! create GC for delimiter line */
			nanoX->gDelimID = GrNewGC();
			/*! set colors for frame */
			GrSetGCForeground(nanoX->gDelimID, YELLOW);
			GrSetGCUseBackground(nanoX->gDelimID, GR_FALSE);
			/*! draw the title delimiter line */
			GrLine(nanoX->gRootWinID, nanoX->gDelimID, 0, WIN_BORDER+14, nanoX->winSizeX, WIN_BORDER+14);						
			/*! create title */
			nanoX->gTitleID = GrNewGC();
			GR_FONT_ID font = GrCreateFont((unsigned char *) FONTNAME, 14, NULL);
			GrSetGCFont(nanoX->gTitleID, font);
			GrDestroyFont(font);
			GrSetGCForeground(nanoX->gTitleID, YELLOW);
			GrText(nanoX->gRootWinID, nanoX->gTitleID, TITLE_X, TITLE_Y,TITLE, -1, GR_TFASCII | GR_TFTOP);
			/*! GC for on/off indicator */
			nanoX->gOnOffID = GrNewGC();			
			GrSetGCUseBackground(nanoX->gOnOffID, GR_FALSE);			
			/*! GC for state text */
			nanoX->gStateTextID = GrNewGC();
			/*! last state text shown is NULL */
			nanoX->lastStateText = NULL;
			/*! set font for state text */
			font = GrCreateFont((unsigned char *) FONTNAME, 14, NULL);
			GrSetGCFont(nanoX->gStateTextID, font);
			GrDestroyFont(font);
			/*! GC for Rstr text */
			nanoX->gRstrTextID = GrNewGC();
			/*! set font for Rstr text */
			font = GrCreateFont((unsigned char *) FONTNAME, 14, NULL);
			GrSetGCFont(nanoX->gRstrTextID, font);
			GrDestroyFont(font);
			/*! GC for Rstr icon */
			nanoX->gRstrIconID = GrNewGC();
			/*! set default coloring for Rstr icon */
			GrSetGCForeground(nanoX->gRstrIconID, RSTR_ICON_COLOR);
			GrSetGCUseBackground(nanoX->gRstrIconID, GR_FALSE);
			/*! GC for Rstr animation */
			nanoX->gRstrAnimID = GrNewGC();
			/*! set default coloring for Rstr animation */
			GrSetGCForeground(nanoX->gRstrAnimID, LTBROWN);
			GrSetGCUseBackground(nanoX->gRstrAnimID, GR_FALSE);
			/*! GC for Espr text */
			nanoX->gEsprTextID = GrNewGC();
			/*! set font for Espr text */
			font = GrCreateFont((unsigned char *) FONTNAME, 14, NULL);
			GrSetGCFont(nanoX->gEsprTextID, font);
			GrDestroyFont(font);	
			/*! GC for Espr icon */
			nanoX->gEsprIconID = GrNewGC();
			/*! set default coloring for icon */
			GrSetGCForeground(nanoX->gEsprIconID, ESPR_ICON_COLOR);
			GrSetGCUseBackground(nanoX->gEsprIconID, GR_FALSE);
			/*! GC for Espr animation */
			nanoX->gEsprAnimID = GrNewGC();
			/*! set default coloring for Espr animation */
			GrSetGCForeground(nanoX->gEsprAnimID, LTBROWN);
			GrSetGCUseBackground(nanoX->gEsprAnimID, GR_FALSE);			
			/*! GC for MlkC text */
			nanoX->gMlkCTextID = GrNewGC();
			/*! set font for MlkC text */
			font = GrCreateFont((unsigned char *) FONTNAME, 14, NULL);
			GrSetGCFont(nanoX->gMlkCTextID, font);
			GrDestroyFont(font);
			/*! GC for MlkC icon */
			nanoX->gMlkCIconID = GrNewGC();
			/*! set default coloring for MlkC icon */
			GrSetGCForeground(nanoX->gMlkCIconID, MLKC_ICON_COLOR);
			GrSetGCUseBackground(nanoX->gMlkCIconID, GR_FALSE);
			/*! GC for Rstr animation */
			nanoX->gMlkCAnimID = GrNewGC();
			/*! set default coloring for Rstr animation */
			GrSetGCForeground(nanoX->gMlkCAnimID, LTBROWN);
			GrSetGCUseBackground(nanoX->gMlkCAnimID, GR_FALSE);
			/*! GC for coffee cups */
			nanoX->gCupID = GrNewGC();
			GrSetGCUseBackground(nanoX->gCupID, GR_FALSE);
			/*! GC for coffee cup underlines */
			nanoX->gCupLineID = GrNewGC();
			GrSetGCUseBackground(nanoX->gCupLineID, GR_FALSE);
			/*! flag success */
			nanoX->err = k2k_NANOX_ERR_SUCCESS;
		}				
	}
	return nanoX;
}

/*!
//
// Releases nanoX ADT "object"
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return noting
//
*/
void k2k_NanoX_Release(k2k_NanoX *nanoX)
{
	if (nanoX != NULL)
	{		
		/*! release GC for delimiter line */
		GrDestroyGC(nanoX->gDelimID);
		/*! release window */
		GrDestroyWindow(nanoX->gRootWinID);
		/*! release GC for state text */
		GrDestroyGC(nanoX->gStateTextID);
		/*! release GC for Rstr text */
		GrDestroyGC(nanoX->gRstrTextID);
		/*! release GC for Rstr icon */
		GrDestroyGC(nanoX->gRstrIconID);
		/*! release GC for Rstr animation */
		GrDestroyGC(nanoX->gRstrAnimID);
		/*! release GC for Espr text */
		GrDestroyGC(nanoX->gEsprTextID);
		/*! release GC for Espr icon */
		GrDestroyGC(nanoX->gEsprIconID);
		/*! release GC for Espr animation */
		GrDestroyGC(nanoX->gEsprAnimID);
		/*! release GC for MlkC text */
		GrDestroyGC(nanoX->gMlkCTextID);
		/*! release GC for MlkC icon */
		GrDestroyGC(nanoX->gMlkCIconID);
		/*! release GC for MlkC animation */
		GrDestroyGC(nanoX->gMlkCAnimID);
		/*! release GC for on/off indicator */
		GrDestroyGC(nanoX->gOnOffID);		
		/*! release memory */
		free(nanoX);	
	}
}


/*!
//
// Draw the main button indicating ON or OFF
// 
// \param mainButtonColor is the color for the on/off button
// 
// \return nothing
//
*/
void k2k_NanoX_DrawOnOffButton(k2k_NanoX *nanoX, MWCOLORVAL mainButtonColor)
{
	GrSetGCForeground(nanoX->gOnOffID, mainButtonColor);
	GrFillEllipse(nanoX->gRootWinID, nanoX->gOnOffID, ONOFF_X, ONOFF_Y, ONOFF_W, ONOFF_H);	
}

/*!
//
// Blink the main button 
// 
// \param mainButtonColor1 is the first color
// \param mainButtonColor2 is the second color
// 
// \return nothing
//
*/
void k2k_NanoX_BlinkOnOffButton(k2k_NanoX *nanoX, MWCOLORVAL mainButtonColor1, MWCOLORVAL mainButtonColor2, int *blinkCounter)
{
	if ((*blinkCounter) % 25 > 12)
	{
		k2k_NanoX_DrawOnOffButton(nanoX, mainButtonColor1);
	}
	else
	{
		k2k_NanoX_DrawOnOffButton(nanoX, mainButtonColor2);
	}
	(*blinkCounter)++;
}

/*!
//
// Displays state text
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// \param stateText is the string to display
// 
// \return nothing
//
*/
void k2k_NanoX_ShowStateText(k2k_NanoX *nanoX, char *stateText)
{
	if (nanoX->lastStateText != NULL)
	{
		/*! "delete" old state text by writing it in black */
		GrSetGCForeground(nanoX->gStateTextID, BLACK);
		GrText(nanoX->gRootWinID, nanoX->gStateTextID, STATE_TEXT_X, STATE_TEXT_Y, nanoX->lastStateText, -1, GR_TFASCII | GR_TFTOP);
		free(nanoX->lastStateText);
		nanoX->lastStateText = NULL;
	}
	/*! show state text */
	nanoX->lastStateText = strdup(stateText);
	GrSetGCForeground(nanoX->gStateTextID, WHITE);
	GrText(nanoX->gRootWinID, nanoX->gStateTextID, STATE_TEXT_X, STATE_TEXT_Y, nanoX->lastStateText, -1, GR_TFASCII | GR_TFTOP);
}

/*!
//
// Show or hide the two coffee cup icons
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// \param cup1Color is the color for the first cup
// \param cup1Color is the color for the second cup
// 
// \return nothing
//
*/
void k2k_NanoX_DrawCups(k2k_NanoX *nanoX, MWCOLORVAL cup1Color, MWCOLORVAL cup2Color)
{
	/*! coffee cup 1 */
	GrSetGCForeground(nanoX->gCupID, cup1Color);
	GrSetGCForeground(nanoX->gCupLineID, cup1Color);
	GrRect(nanoX->gRootWinID, nanoX->gCupID, CUP1_X, CUP1_Y, CUP_H, CUP_W);		
	GrLine(nanoX->gRootWinID, nanoX->gCupLineID, CUPLINE1_X1, CUPLINE1_Y1, CUPLINE1_X2, CUPLINE1_Y2);							
	/*! coffe cup 2 */
	GrSetGCForeground(nanoX->gCupID, cup2Color);
	GrSetGCForeground(nanoX->gCupLineID, cup2Color);	
	GrRect(nanoX->gRootWinID, nanoX->gCupID, CUP2_X, CUP2_Y, CUP_H, CUP_W);			
	GrLine(nanoX->gRootWinID, nanoX->gCupLineID, CUPLINE2_X1, CUPLINE2_Y1, CUPLINE2_X2, CUPLINE2_Y2);						
}

/*!
//
// Blink the coffee cup icons
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// \param fillDegreee is the level of the coffeee
// \param coffeeCount is the number of coffees to make
// \param coffeeCountDone is the number of coffees already made
// 
// \return nothing
//
*/
void k2k_NanoX_BlinkCups(k2k_NanoX *nanoX, int fillDegreee, int coffeeCount, int coffeeCountDone)
{
	MWCOLORVAL cup1Color = coffeeCountDone > 0 ? GRAY : WHITE;
	MWCOLORVAL cup2Color = coffeeCount > 1 ? WHITE : BLACK;
	if (fillDegreee % 25 > 12)
	{
		cup1Color = coffeeCountDone > 0 ? GRAY : BLACK;
		cup2Color = coffeeCountDone > 0 ? BLACK : cup2Color;
	}
	k2k_NanoX_DrawCups(nanoX, cup1Color, cup2Color);
}

/*!
//
// Displays text for Rstr
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_ShowRstrText(k2k_NanoX *nanoX)
{
	/*! set default coloring for Rstr text */
	GrSetGCForeground(nanoX->gRstrTextID, RSTR_ICON_COLOR);
	/*! show text */
	GrText(nanoX->gRootWinID, nanoX->gRstrTextID, RSTR_TEXT_X, RSTR_TEXT_Y, RSTR_TEXT, -1, GR_TFASCII | GR_TFTOP);
}

/*!
//
// Deletes text for Rstr by writing it in black
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_HideRstrText(k2k_NanoX *nanoX)
{
	/*! set black color */
	GrSetGCForeground(nanoX->gRstrTextID, BLACK);
	/*! "delete" text */
	GrText(nanoX->gRootWinID, nanoX->gRstrTextID, RSTR_TEXT_X, RSTR_TEXT_Y, RSTR_TEXT, -1, GR_TFASCII | GR_TFTOP);
}

/*!
//
// Displays icon for Rstr
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_ShowRstrIcon(k2k_NanoX *nanoX)
{
	/*! set default coloring for Rstr text */	
	GrSetGCForeground(nanoX->gRstrIconID, RSTR_ICON_COLOR);
	/*! show Rstr icon */
	GrRect(nanoX->gRootWinID, nanoX->gRstrIconID, RSTR_ICON_X, RSTR_ICON_Y, RSTR_ICON_W, RSTR_ICON_H);
}

/*!
//
// Deletes icon for Rstr by writing it in black
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_HideRstrIcon(k2k_NanoX *nanoX)
{
	/*! set black color */
	GrSetGCForeground(nanoX->gRstrIconID, BLACK);
	/*! "delete" text */
	GrRect(nanoX->gRootWinID, nanoX->gRstrIconID, RSTR_ICON_X, RSTR_ICON_Y, RSTR_ICON_W, RSTR_ICON_H);
}

/*!
//
// Update Rstr animation
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// \param fillDegree is the pointer to the level of the coffee
// 
// \return nothing
//
*/
void k2k_NanoX_UpdateRstrAnimation(k2k_NanoX *nanoX, int *fillDegree)
{
	k2k_NanoX_UpdateAnimation(nanoX, nanoX->gRstrAnimID, RSTR_ICON_X, RSTR_ICON_Y, RSTR_ICON_W, RSTR_ICON_H, fillDegree);
}

/*!
//
// Displays text for Espr
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_ShowEsprText(k2k_NanoX *nanoX)
{
	/*! set default coloring for Espr text */
	GrSetGCForeground(nanoX->gEsprTextID, ESPR_ICON_COLOR);
	/*! show text */
	GrText(nanoX->gRootWinID, nanoX->gEsprTextID, ESPR_TEXT_X, ESPR_TEXT_Y, ESPR_TEXT, -1, GR_TFASCII | GR_TFTOP);
}

/*!
//
// Deletes text for Espr by writing it in black
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_HideEsprText(k2k_NanoX *nanoX)
{
	/*! set black color */
	GrSetGCForeground(nanoX->gEsprTextID, BLACK);
	/*! "delete" text */
	GrText(nanoX->gRootWinID, nanoX->gEsprTextID, ESPR_TEXT_X, ESPR_TEXT_Y, ESPR_TEXT, -1, GR_TFASCII | GR_TFTOP);
}

/*!
//
// Displays icon for Espr
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_ShowEsprIcon(k2k_NanoX *nanoX)
{
	/*! set default coloring for Espr icon */	
	GrSetGCForeground(nanoX->gEsprIconID, ESPR_ICON_COLOR);
	/*! show Espr icon */
	GrRect(nanoX->gRootWinID, nanoX->gEsprIconID, ESPR_ICON_X, ESPR_ICON_Y, ESPR_ICON_W, ESPR_ICON_H);
}

/*!
//
// Deletes icon for Espr by writing it in black
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_HideEsprIcon(k2k_NanoX *nanoX)
{
	/*! set black color */
	GrSetGCForeground(nanoX->gEsprIconID, BLACK);
	/*! "delete" text */
	GrRect(nanoX->gRootWinID, nanoX->gEsprIconID, ESPR_ICON_X, ESPR_ICON_Y, ESPR_ICON_W, ESPR_ICON_H);
}

/*!
//
// Update Espr animation
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// \param fillDegree is the pointer to the level of the coffee
// 
// \return nothing
//
*/
void k2k_NanoX_UpdateEsprAnimation(k2k_NanoX *nanoX, int *fillDegree)
{
	k2k_NanoX_UpdateAnimation(nanoX, nanoX->gEsprAnimID, ESPR_ICON_X, ESPR_ICON_Y, ESPR_ICON_W, ESPR_ICON_H, fillDegree);
}

/*!
//
// Displays text for MlkC
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_ShowMlkCText(k2k_NanoX *nanoX)
{
	/*! set default coloring for MlkC text */
	GrSetGCForeground(nanoX->gMlkCTextID, MLKC_ICON_COLOR);
	/*! show text */
	GrText(nanoX->gRootWinID, nanoX->gMlkCTextID, MLKC_TEXT_X, MLKC_TEXT_Y, MLKC_TEXT, -1, GR_TFASCII | GR_TFTOP);
}

/*!
//
// Deletes text for MlkC by writing it in black
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_HideMlkCText(k2k_NanoX *nanoX)
{
	/*! set black color */
	GrSetGCForeground(nanoX->gMlkCTextID, BLACK);
	/*! "delete" text */
	GrText(nanoX->gRootWinID, nanoX->gMlkCTextID, MLKC_TEXT_X, MLKC_TEXT_Y, MLKC_TEXT, -1, GR_TFASCII | GR_TFTOP);
}

/*!
//
// Displays icon for MlkC
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_ShowMlkCIcon(k2k_NanoX *nanoX)
{
	/*! set default coloring for MlkC icon */	
	GrSetGCForeground(nanoX->gMlkCIconID, MLKC_ICON_COLOR);
	/*! show Espr icon */
	GrRect(nanoX->gRootWinID, nanoX->gMlkCIconID, MLKC_ICON_X, MLKC_ICON_Y, MLKC_ICON_W, MLKC_ICON_H);
}

/*!
//
// Deletes icon for MlkC by writing it in black
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// 
// \return nothing
//
*/
void k2k_NanoX_HideMlkCIcon(k2k_NanoX *nanoX)
{
	/*! set black color */
	GrSetGCForeground(nanoX->gMlkCIconID, BLACK);
	/*! "delete" text */
	GrRect(nanoX->gRootWinID, nanoX->gMlkCIconID, MLKC_ICON_X, MLKC_ICON_Y, MLKC_ICON_W, MLKC_ICON_H);
}

/*!
//
// Update MlkC animation
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// \param fillDegree is the pointer to the level of the coffee
// 
// \return nothing
//
*/
void k2k_NanoX_UpdateMlkCAnimation(k2k_NanoX *nanoX, int *fillDegree)
{
	k2k_NanoX_UpdateAnimation(nanoX, nanoX->gMlkCAnimID, MLKC_ICON_X, MLKC_ICON_Y, MLKC_ICON_W, MLKC_ICON_H, fillDegree);
}

/*!
//
// Update animation
// 
// \param nanoX is the pointer to the k2k_NanoX structure 
// \param gID is the graphic context id of the animation
// \param X is the coordinate on the X axis 
// \param Y is the coordinate on the Y axis 
// \param H is the height
// \param fillDegree is the level of the coffee in the animation  
// 
// \return nothing
//
*/
static void k2k_NanoX_UpdateAnimation(k2k_NanoX *nanoX, GR_GC_ID gAnimID, int X, int Y, int W, int H, int *fillDegree)
{
	if ((*fillDegree) == 0)
	{
		/*! clear animation, paint black rectangle in AND mode */
		GrSetGCMode(gAnimID, GR_MODE_AND);
		GrSetGCForeground(gAnimID, BLACK);
		GrFillRect(nanoX->gRootWinID, gAnimID, X + 1, Y + 1, W - 2, H - 2);
	}
	else
	{
		/*! show animation, paint brown rectangle in XOR mode */
		GrSetGCMode(gAnimID, GR_MODE_XOR);
		GrSetGCForeground(gAnimID, LTBROWN);
		GrFillRect(nanoX->gRootWinID, gAnimID, X + 1, Y + 1, W - 2, (*fillDegree));
		
	}
	/*! update fill degree */
	(*fillDegree) = ((*fillDegree) + 1) % (RSTR_ICON_H - 2);
}
